package com.elvin.platform.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.elvin.platform.beans.*;
import com.elvin.platform.service.TencentSmsService;
import com.elvin.platform.service.UserOrganizationService;
import com.elvin.platform.service.UserService;
import com.elvin.platform.util.HttpUtil;
import com.elvin.platform.util.MD5Utils;
import com.elvin.platform.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Controller
@RestController
@Log4j2
@RequestMapping("/PcLoginController")
@Api("PC端登录")
public class PcLoginController {

    @Resource
    private UserService userService;
    @Resource
    private UserOrganizationService userOrganizationService;

    @Autowired
    private TencentSmsService tencentSmsService;


    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @ApiOperation(value = "新增用户")
    @PostMapping("/insert")
    public Result<Object> insert(
            @ApiParam("用户名称") @RequestParam(value = "userName", required = true)String userName,
            @ApiParam("密码") @RequestParam(value = "password", required = true)String password,
            @ApiParam("昵称") @RequestParam(value = "nickName", required = false)String nickName) {
        Result<Object> result = new Result<>();
        try {

            EntityWrapper<User> wrapper = new EntityWrapper<>();
            wrapper.eq("user_name", userName);
            //根据userName校验是否存在
            User user1 = userService.selectOne(wrapper);
            if (user1 !=null){
                result.fail(null, "用户名已经存在，不能重复新增！");
            }else{
                User user = new User();
                user.setUserName(userName);
                String s = MD5Utils.md5(password);
                user.setPassword(s);
                user.setNickName(nickName);
                user.setRoleId("1");
                userService.insert(user);
                //用户添加成功之后向组织表插入数据

                UserOrganization userOrganization = new UserOrganization();
                userOrganization.setOrganizeId(1L);
                userOrganization.setUserId(user.getId());
                userOrganization.setOrganizeName("演示组");
                userOrganizationService.insert(userOrganization);

                result.success(null, "用户添加成功！");
            }
        } catch (Exception e) {
            log.debug(e.getMessage());
            result.fail(null, e.getMessage());
        }
        return result;
    }

    @ApiOperation(value = "登录")
    @PostMapping("/login")
    public Result<Object> login(
        @RequestBody PcLogin entity
    )
    {
        Result<Object> result = new Result<>();
        try {
          String user_name = entity.getUserName();
          String password = entity.getPassword();
            //先校验用户名是否存在
            EntityWrapper<User> wrapper = new EntityWrapper<>();
            wrapper.eq("user_name", user_name);
            //根据userName校验是否存在
            User user1 = userService.selectOne(wrapper);
            if (user1 !=null){
                //校验用户和密码
                String md5Pw = MD5Utils.md5(password);
                wrapper.eq("password", md5Pw);
                User user2 = userService.selectOne(wrapper);
                if (user2 !=null){
                    //用户密码校验正确, 1、更新登录时间
                    user2.setLoginTime(new Date());
                    userService.updateById(user2);
                    //2、返回token
                    String grantType = "client_credential";
                    String appId = "wxd8dd4e82e253829f";
                    String appSecret = "b78154bee673b9072ee16e4062d3c053";
                    Map<String, String> requestUrlParam = new HashMap<>();
                    requestUrlParam.put("appid", appId); // 开发者设置中的appId
                    requestUrlParam.put("secret", appSecret); // 开发者设置中的appSecret
                    requestUrlParam.put("grant_type", grantType); // 默认参数
                    JSONObject json = JSONObject.parseObject(HttpUtil.sendPost("https://api.weixin.qq.com/cgi-bin/token", requestUrlParam));
                    log.debug("getAccessToken json = {}", json);
                    String access_token = json.getString("access_token");
                    int expires_in = (Integer.parseInt(json.getString("expires_in"))) ;
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("access_token", access_token);
                    resultMap.put("expires_in", expires_in);
                    resultMap.put("user",user2);
                    result.success(resultMap,"登录成功！");
                }else{
                    result.setStatus(1);
                    result.setMsg("密码错误，请重新输入！");
                }
            }else{
                result.setStatus(-1);
                result.setMsg("用户名不存在，请确认！");
            }
        } catch (Exception e) {
            log.debug(e.getMessage());
            result.fail(null, e.getMessage());
        }
        return result;
    }

    @ApiOperation(value = "重置密码")
    @PostMapping("/resetPassword")
    public Result<Object> resetPassword(
            @ApiParam("用户id")@RequestParam(value = "user_id", required = true) Long user_id,
            @ApiParam("新密码")@RequestParam(value = "password", required = true) String password)
    {
        Result<Object> result = new Result<>();
        try {
            EntityWrapper<User> wrapper = new EntityWrapper<>();
            wrapper.eq("id", user_id);
            User user = new User();
            user.setId(user_id);
            user.setPassword(MD5Utils.md5(password));
            //根据userName校验是否存在
            userService.updateById(user);
            result.setMsg("密码重置成功！");
        } catch (Exception e) {
            log.debug(e.getMessage());
            result.fail(null, e.getMessage());
        }
        return result;
    }


    @ApiOperation(value = "密码修改")
    @PostMapping("/updatePassword")
    public Result<Object> updatePassword(
            @ApiParam("用户id")@RequestParam(value = "userId", required = true) Long user_id,
            @ApiParam("旧密码")@RequestParam(value = "oldPassword", required = true) String oldPassword,
            @ApiParam("新密码")@RequestParam(value = "newPassword", required = true) String newPassword
            )
    {
        Result<Object> result = new Result<>();
        try {
            //先校验旧密码是否正确
            EntityWrapper<User> wrapper = new EntityWrapper<>();
            wrapper.eq("id", user_id);
            wrapper.eq("password", MD5Utils.md5(oldPassword));
            User user1 = userService.selectOne(wrapper);
            if(user1 !=null){
                user1.setPassword(MD5Utils.md5(newPassword));
               // userService.update(user1,wrapper);
                userService.updateById(user1);
                result.success(null,"密码修改成功！");
            }else{
                result.setStatus(1);
                result.setMsg("旧密码错误！");
            }
        } catch (Exception e) {
            log.debug(e.getMessage());
            result.fail(null, e.getMessage());
        }
        return result;
    }


    @ApiOperation(value = "绑定手机号码")
    @PostMapping("/bindPhone")
    public Result<Object> bindPhone(
            @ApiParam("用户id")@RequestParam(value = "userId", required = true) Long user_id,
            @ApiParam("手机号码")@RequestParam(value = "telephone", required = true) String telephone
    )
    {
        Result<Object> result = new Result<>();
        try {
            //先校验手机号码是否唯一
            EntityWrapper<User> wrapper = new EntityWrapper<>();
            //wrapper.eq("id", user_id);
            wrapper.eq("telephone", telephone);
            User user1 = userService.selectOne(wrapper);
            if(user1 !=null){
                result.setStatus(1);
                result.setMsg("手机号码已存在！");
            }else{
                User user = new User();
                user.setId(user_id);
                user.setTelephone(telephone);
                userService.updateById(user);
                result.success(null,"手机号码绑定成功！");
            }
        } catch (Exception e) {
            log.debug(e.getMessage());
            result.fail(null, e.getMessage());
        }
        return result;
    }

    @ApiOperation(value = "绑定邮箱")
    @PostMapping("/bindEmail")
    public Result<Object> bindEmail(
            @ApiParam("用户id")@RequestParam(value = "userId", required = true) Long user_id,
            @ApiParam("邮箱")@RequestParam(value = "email", required = true) String email
    )
    {
        Result<Object> result = new Result<>();
        try {
            //先校验邮箱是否唯一
            EntityWrapper<User> wrapper = new EntityWrapper<>();
            //wrapper.eq("id", user_id);
            wrapper.eq("email", email);
            User user1 = userService.selectOne(wrapper);
            if(user1 !=null){
                result.setStatus(1);
                result.setMsg("邮箱已存在！");
            }else{
                User user = new User();
                user.setId(user_id);
                user.setEmail(email);
                userService.updateById(user);
                result.success(null,"邮箱绑定成功！");
            }
        } catch (Exception e) {
            log.debug(e.getMessage());
            result.fail(null, e.getMessage());
        }
        return result;
    }

  /**
   * 发送短信验证码
   */
  @PostMapping("/sendSmsCode")
  public Result<Object> sendSmsCode(@RequestParam("telephone") String telephone) {
    //校验手机号码
    //校验手机号码
    Result<Object> result = new Result<>();
    Map<String, Object> map = new HashMap<>();
    map.put("telephone", telephone);
    List<User> users = userService.selectByMap(map);
    if (users.size()<1) {
      result.setStatus(1);
      result.setMsg("根据电话号码没有查询到用户！");
      return result;
    }else if(users.size()>1){
      result.setStatus(1);
      result.setMsg("根据电话号码查询到"+users.size()+"条用户信息！");
      return result;
    }
      // 生成6位数字验证码
      String code = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));
      // 将验证码保存到Redis中
      redisTemplate.opsForValue().set(telephone, code, 5, TimeUnit.MINUTES);
      // 发送短信验证码
      tencentSmsService.sendSmsCode(telephone, code);
      result.success(null,"验证码已发送！");
    return result;
  }


  /**
   * 登陆接口
   */
  @PostMapping("/smsLogin")
  public Result<Object> smsLogin(@RequestParam("telephone") String telephone, @RequestParam("code") String code) {
    Result<Object> result = new Result<>();
    // 根据手机号码从Redis中获取验证码
    String smsCode = redisTemplate.opsForValue().get(telephone);
    if (StringUtils.isEmpty(smsCode)) {
      result.setStatus(1);
      result.setMsg("验证码已过期，请重新发送！");
      return result;
    }
    if (!smsCode.equals(code)) {
      result.setStatus(1);
      result.setMsg("验证码错误！");
      return result;
    }

    //用户密码校验正确, 1、更新登录时间
    EntityWrapper<User> wrapper = new EntityWrapper<>();
    wrapper.eq("telephone", telephone);
    //2、返回token
    User user2 = userService.selectOne(wrapper);
    if (user2 !=null){
      //用户密码校验正确, 1、更新登录时间
      user2.setLoginTime(new Date());
      userService.updateById(user2);
      String grantType = "client_credential";
      String appId = "wxd8dd4e82e253829f";
      String appSecret = "b78154bee673b9072ee16e4062d3c053";
      Map<String, String> requestUrlParam = new HashMap<>();
      requestUrlParam.put("appid", appId); // 开发者设置中的appId
      requestUrlParam.put("secret", appSecret); // 开发者设置中的appSecret
      requestUrlParam.put("grant_type", grantType); // 默认参数
      JSONObject json = JSONObject.parseObject(HttpUtil.sendPost("https://api.weixin.qq.com/cgi-bin/token", requestUrlParam));
      log.debug("getAccessToken json = {}", json);
      String access_token = json.getString("access_token");
      int expires_in = (Integer.parseInt(json.getString("expires_in"))) ;
      Map<String, Object> resultMap = new HashMap<>();
      resultMap.put("access_token", access_token);
      resultMap.put("expires_in", expires_in);
      resultMap.put("user",user2);
      result.success(resultMap,"登录成功！");
    }else{
      result.setStatus(1);
      result.setMsg("根据电话号码没有查找到用户信息！");
    }
    return result;
  }

}

